package util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.users.User;
import play.libs.Json;
import services.DAO;
import enums.Role;

/**
 * Aquí se crean las entidades simples con la información muy relevante para
 * cada rol, esta entidad se va a serializar a json y guardar en la session como
 * una cookie así que debe ser lo más minimalista posible.
 * 
 * @author Caeus
 * 
 */
public class SessionObj {
	private Long id;

	private Acudiente acudiente;
	private Profesor profesor;
	private Coordinador coordinador;
	private Supadmin supadmin;

	public SessionObj() {

	}

	public String toJson() {
		return Json.toJson(this).toString();
	}

	public static SessionObj instantiate(User user) {

		List<Object[]> oo = DAO
				.executeNative(
						"SELECT x.id,'ACUDIENTE' FROM acudiente x WHERE x.id_persona=?id "
								+ "UNION "
								+ "SELECT x.id,'PROFESOR' FROM profesor x WHERE x.id_persona=?id "
								+ "UNION "
								+ "SELECT x.id,'COORDINADOR' FROM coordinador x WHERE x.id_persona=?id "
								+ "UNION "
								+ "SELECT x.id,'SUPADMIN' FROM supadmin x WHERE x.id_persona=?id ",
						-1, "id", user.getId());
		SessionObj so = new SessionObj();
		so.setId(user.getId());
		for (Object[] o : oo) {
			Role rol = Role.valueOf((String) o[1]);
			Long idActor = ((Long) o[0]).longValue();
			switch (rol) {
			case ACUDIENTE:
				so.setAcudiente(Acudiente.instantiate(idActor));
				break;
			case PROFESOR:
				so.setProfesor(Profesor.instantiate(idActor));
				break;
			case COORDINADOR:
				so.setCoordinador(Coordinador.instantiate(idActor));
				break;
			case SUPADMIN:
				so.setSupadmin(Supadmin.instantiate(idActor));
				break;
			}

		}
		return so;
	}

	public Long getId() {
		return id;
	}

	public Acudiente getAcudiente() {
		return acudiente;
	}

	public void setAcudiente(Acudiente acudiente) {
		this.acudiente = acudiente;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Profesor getProfesor() {
		return profesor;
	}

	public void setProfesor(Profesor profesor) {
		this.profesor = profesor;
	}

	public Coordinador getCoordinador() {
		return coordinador;
	}

	public void setCoordinador(Coordinador coordinador) {
		this.coordinador = coordinador;
	}

	public Supadmin getSupadmin() {
		return supadmin;
	}

	public void setSupadmin(Supadmin supadmin) {
		this.supadmin = supadmin;
	}

	public static class Acudiente {

		private Long id;
		private Map<Long, Estudiante> estudiantes;

		public Acudiente() {

		}

		public Map<Long, Estudiante> getEstudiantes() {
			return estudiantes;
		}

		public void setEstudiantes(Map<Long, Estudiante> estudiantes) {
			this.estudiantes = estudiantes;
		}

		public Long getId() {
			return id;
		}

		public void setId(Long id) {
			this.id = id;
		}

		public static Acudiente instantiate(Long id) {
			Acudiente acu = new Acudiente();
			acu.setId(id);
			HashMap<Long, Estudiante> estudiantes = new HashMap<Long, Estudiante>();
			acu.setEstudiantes(estudiantes);
			List<Object[]> oo = DAO
					.executeNative(
							"SELECT e.id, e.id_colegio FROM estudiante e where e.id_acudiente=?idAcudiente",
							-1, "idAcudiente", id);
			for (Object[] o : oo) {
				Estudiante e = new Estudiante(((Number) o[0]).longValue(),
						((Number) o[1]).longValue());
				estudiantes.put(e.getId(), e);
			}
			return acu;
		}
	}

	public static class Estudiante {
		private Long id;
		private Long idColegio;

		public Estudiante(Long id, Long idColegio) {
			this.id = id;
			this.setIdColegio(idColegio);
		}

		public Estudiante() {

		}

		public Long getId() {
			return id;
		}

		public void setId(Long id) {
			this.id = id;
		}

		public Long getIdColegio() {
			return idColegio;
		}

		public void setIdColegio(Long idColegio) {
			this.idColegio = idColegio;
		}

	}

	public static class Profesor {
		private Long id;
		private Long idColegio;

		public Long getId() {
			return id;
		}

		public void setId(Long id) {
			this.id = id;
		}

		public Long getIdColegio() {
			return idColegio;
		}

		public void setIdColegio(Long idColegio) {
			this.idColegio = idColegio;
		}

		public static Profesor instantiate(Long id) {
			models.Profesor p = DAO.find(models.Profesor.class, id);
			Profesor pro = new Profesor();
			pro.setId(p.getId());
			pro.setIdColegio(p.getIdColegio());
			return pro;
		}
	}

	public static class Coordinador {
		private Long id;
		private Long idColegio;

		public Long getId() {
			return id;
		}

		public void setId(Long id) {
			this.id = id;
		}

		public Long getIdColegio() {
			return idColegio;
		}

		public void setIdColegio(Long idColegio) {
			this.idColegio = idColegio;
		}

		public static Coordinador instantiate(Long id) {
			models.Coordinador c = DAO.find(models.Coordinador.class, id);
			Coordinador cor = new Coordinador();
			cor.setId(c.getId());
			cor.setIdColegio(c.getIdColegio());
			return cor;
		}
	}

	public static class Supadmin {
		private Long id;

		public Supadmin() {

		}

		public Long getId() {
			return id;
		}

		public static Supadmin instantiate(final Long id) {
			return new Supadmin() {
				{
					setId(id);
				}
			};
		}

		public void setId(Long id) {
			this.id = id;
		}

	}

}
